package com.mck.aop;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mck.entity.OperLog;
import com.mck.interceptor.TokenInterceptor;
import com.mck.service.OperationLogService;
import com.mck.utils.IpLocationUtil;
import com.mck.utils.NullRemover;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @version 1.0.0
 * @Author mck
 * @Date 2025/4/23 下午12:25
 * @注释
 */

@Aspect
@Component
@Slf4j
public class OperationLogAspect {

    @Autowired
    private OperationLogService operationLogService;
    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Around("@annotation(com.mck.anno.OperationLog)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        // 获取请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

        // 获取用户ID
        Integer userId = tokenInterceptor.getUserIdFromToken(request.getHeader("Authorization"));
        if (userId == null) {
            return joinPoint.proceed();
        }

        // 获取IP
        String ip = IpLocationUtil.getIp(request);

        // 获取地址
        String address = IpLocationUtil.getAddress(ip);

        // 计算开始时间
        long startTime = System.currentTimeMillis();

        // 获取参数
        String params = Arrays.stream(joinPoint.getArgs())
                .map(arg -> {
                    if (arg == null) return "null";
                    try {
                        return new ObjectMapper().writeValueAsString(NullRemover.removeNull(arg));
                    } catch (Exception e) {
                        return arg.toString();
                    }
                })
                .collect(Collectors.joining(", ", "[", "]"));

        // 长度检查
        int originalLength = params.length();
        if (originalLength > 500) {
            params = params.substring(0, 500) + "...[truncated]";
            log.warn("操作日志参数截断，原始长度: {}", originalLength);
        }

        try {
            // 执行目标方法
            Object result = joinPoint.proceed();

            // 计算结束时间
            long endTime = System.currentTimeMillis();
            // 计算耗时
            long timeCost = endTime - startTime;

            // 创建操作日志对象
            OperLog operationLog = new OperLog();
            operationLog.setUserId(userId);
            operationLog.setMethod(request.getMethod());
            operationLog.setUrl(request.getRequestURI());
            operationLog.setParams(params);
            operationLog.setIp(ip);
            operationLog.setAddress(address);
            operationLog.setCreateTime(LocalDateTime.now());
            operationLog.setTimeCost(timeCost);

            // 保存操作日志
            operationLogService.saveOperationLog(operationLog);

            return result;
        } catch (Exception e) {
            log.error("操作日志记录失败", e);
            throw e;
        }
    }

    // private String getIp(HttpServletRequest request) {
    //     String ip = null;
    //
    //     // 检查多级代理的X-Forwarded-For，取第一个有效IP
    //     String[] headers = {"X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
    //     for (String header : headers) {
    //         ip = request.getHeader(header);
    //         if (isValidIp(ip)) {
    //             // 处理多级代理的情况（取第一个非unknown的IP）
    //             int index = ip.indexOf(',');
    //             if (index != -1) {
    //                 ip = ip.substring(0, index).trim();
    //             }
    //             break;
    //         }
    //     }
    //     // 直接获取远程地址
    //     if (!isValidIp(ip)) {
    //         ip = request.getRemoteAddr();
    //     }
    //     // 规范化IPv6本地地址
    //     if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip)) {
    //         ip = "127.0.0.1";
    //     }
    //     return ip;
    // }

    // /**
    //  * 验证IP地址字符串是否有效
    //  *
    //  * @param ip 待验证的IP地址字符串
    //  * @return 当满足以下所有条件时返回true：
    //  *         1. ip不为null
    //  *         2. ip不是空字符串
    //  *         3. ip不等于"unknown"（不区分大小写）
    //  *         否则返回false
    //  */
    // private boolean isValidIp(String ip) {
    //     return ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip);
    // }
}
